<template>
  <div class="logic-flow">
    <div id="logic-container"></div>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, computed, onMounted } from 'vue';
import { useStore } from 'vuex';
import LogicFlow from '@logicflow/core';
import {
  Menu,
  DndPanel,
  Control,
  SelectionSelect,
  InsertNodeInPolyline,
} from '@logicflow/extension';
import '@logicflow/core/dist/style/index.css';
import '@logicflow/extension/lib/style/index.css';
import { GetLogicMenu, GetLogicPanel } from '@/model/logic/plugins';
import {
  TransactorNode,
  ApproveNode,
  CopyNode,
  StartNode,
  EndNode,
} from '@/model/logic/node';
import eventBus from '@/core/eventBus';
import { EdgeType } from '@/views/flowDesign/constant';

LogicFlow.use(Menu);
LogicFlow.use(DndPanel);
LogicFlow.use(Control);
LogicFlow.use(SelectionSelect);
LogicFlow.use(InsertNodeInPolyline);

export default defineComponent({
  name: 'LogicFlow',
  components: {},
  setup() {
    const lf: any = ref({});
    const store = useStore();
    const nodes = computed({
      get: () => store.state.flowDesign.nodes,
      set: (val) => store.commit('flowDesign/SetNodes', val),
    });
    const edges = computed({
      get: () => store.state.flowDesign.edges,
      set: (val) => store.commit('flowDesign/SetEdges', val),
    });

    eventBus.on('node-property-change', (data: any) => {
      lf.value.updateText(data.id, data.val);
    });
    eventBus.on('flow-define-refresh', () => {
      lf.value.render({
        nodes: nodes.value,
        edges: edges.value,
      });
    });
    eventBus.on('flow-design-save', (data: any) => {
      const { nodes, edges } = lf.value.getGraphData();
      store.commit('flowDesign/SetNodeEdge', { nodes, edges });
    });

    onMounted(() => {
      const container = document.querySelector(
        '#logic-container',
      ) as HTMLElement;
      lf.value = new LogicFlow({
        container,
        grid: true,
      });
      lf.value.batchRegister([
        TransactorNode,
        ApproveNode,
        CopyNode,
        StartNode,
        EndNode,
      ]);
      lf.value.extension.menu.setMenuConfig({
        nodeMenu: GetLogicMenu(lf.value), // 覆盖默认的节点右键菜单
        edgeMenu: GetLogicMenu(lf.value, 'edge'), // 删除默认的边右键菜单
        // graphMenu: [], // 覆盖默认的边右键菜单，与false表现一样
      });
      lf.value.extension.dndPanel.setPatternItems(GetLogicPanel(lf));
      lf.value.render({
        nodes: nodes.value,
        edges: edges.value,
      });
      lf.value.on('node:add', (record: any) => {
        record.data.properties.nodeId.defaultValue = record.data.id;
        record.data.properties.nodeName.defaultValue = record.data.text.value;
        nodes.value.push(record.data);
      });
      lf.value.on('node:dnd-add', (record: any) => {
        record.data.properties.nodeId.defaultValue = record.data.id;
        record.data.properties.nodeName.defaultValue = record.data.text.value;
        nodes.value.push(record.data);
      });
      lf.value.on('node:delete', (record: any) => {
        nodes.value = nodes.value.filter((it: any) => it.id !== record.data.id);
      });
      lf.value.on('node:click', (record: any) => {
        store.commit('flowDesign/SetCurNodeId', record.data.id);
      });
      lf.value.on('blank:click', (record: any) => {
        store.commit('flowDesign/SetCurNodeId', '');
      });
      lf.value.on('text:update', (record: any) => {
        // 节点文本更改
        if (!EdgeType.includes(record.type)) {
          store.commit('flowDesign/setNodeName', {
            id: record.id,
            value: record.text,
          });
        }
      });
    });

    return {};
  },
});
</script>
<style lang="less" scoped>
.logic-flow {
  flex: auto;
  height: calc(100% - 4px);
  margin-right: 12px;
  #logic-container {
    width: 100%;
    height: 100%;
    :deep .select-node {
      // 控制选区节点样式
      .lf-dnd-shape {
        cursor: pointer;
      }
    }
  }
}
</style>
